<template>
	<div class="volume">
		<div class="header">
			<el-form inline>
				<el-form-item label="存储池">
					<el-select class="mr10 width-150" v-model="poolName" placeholder="请选择存储池" v-loading="!poolName" @change="changePool">
						<el-option v-for="pool of poolList" :key="pool.poolId" :value="pool.poolName" :label="pool.poolName" />
					</el-select>
				</el-form-item>
				<el-form-item label="存储卷" :error="poolName&&!volumeName?'请选择存储卷':''">
					<el-select class="width-150" v-model="volumeName" placeholder="请选择存储卷" v-loading="!poolName" @change="changeVolume">
						<el-option v-for="volume of volumeList" :key="volume.id" :value="volume.rbdName" :label="volume.rbdName" />
					</el-select>
				</el-form-item>
			</el-form>
		</div>
		<div class="content" v-if="isChart">
			<el-card>
				<Line title="OPS" name="ops" :data="state.opsData" :x-interval-show="2" y-unit="次/秒"/>
			</el-card>
			<el-card>
				<Line title="BPS" name="bps" :data="state.bpsData" :x-interval-show="2" y-unit="B/s"/>
			</el-card>
			<el-card class="w100">
				<Line title="平均延迟" name="delay" :data="state.delayData" y-unit="ns" />
			</el-card>
		</div>
	</div>
</template>
<script lang="ts" setup>
import { computed, defineAsyncComponent, inject, onUnmounted, reactive, Ref, ref, watch } from 'vue';
import { useMonitorApi } from '/@/api/monitor-center';
import { dayjs, ElMessageBox } from 'element-plus';
import { LineChartData } from '/@/types';
import { lineTimeHandle, fillDates } from '/@/utils/other';
import { opsMap } from '/@/utils/const';

interface DataState{
	opsData:LineChartData;
	bpsData:LineChartData;
	delayData:LineChartData;
}

const Line = defineAsyncComponent(() => import('/@/components/echarts/line.vue'));

const monitorApi = useMonitorApi();
const poolList = inject<Ref<any[]>>('pool-list', ref([]));
const poolName = ref();
const _volumeList = inject<Ref<any[]>>('volume-list', ref([]));
const volumeList = computed(() => {
	return poolName.value ? _volumeList.value.filter((item:any) => item.poolName === poolName.value) : [];
});
const volumeName = ref();
const state = reactive<DataState>({
	opsData: {
		seriesNames: [],
		seriesData: []
	},
	bpsData: {
		seriesNames: [],
		seriesData: []
	},
	delayData: {
		seriesNames: [],
		seriesData: []
	}
});
const isChart = ref(false);
const datetimerange = inject('datetimerange', ref());
const defaultdaterange = inject('defaultdaterange', ref());
// open rbd performance
const openRbdMon = () => {
	ElMessageBox.confirm(
		'无法获取该存储池下存储卷的监控数据，是否开启该存储卷的监控特性？',
		'警告',
		{
			confirmButtonText: '确定',
			cancelButtonText: '取消',
			type: 'warning',
			draggable: true,
			beforeClose: (action, instance, done) => {
				if (action === 'confirm') {
					instance.confirmButtonLoading = true;
					instance.confirmButtonText = '开启中';
					monitorApi.openRbdMon({ poolName: poolName.value }).then(() => {
						isChart.value = true;
					}).finally(() => {
						done();
					});
				} else {
					done();
				}
			},
		}
	).then(() => getRbdMon());
};
// get data
const getRbdMon = () => {
	if (!poolName.value || !volumeName.value) return;
	const parmas = {
		poolName: poolName.value,
		rbdName: volumeName.value,
		durationVO: {
			start: datetimerange.value ? datetimerange.value[0] : dayjs().subtract(defaultdaterange.value[0], defaultdaterange.value[1]).format('YYYY-MM-DD HH:mm:ss'),
			end: datetimerange.value ? datetimerange.value[1] : dayjs().format('YYYY-MM-DD HH:mm:ss'),
		}
	};
	monitorApi.getRbdMon(parmas).then((res:any) => {
		const ops = fillDates(parmas.durationVO.start, res.data.ops);
		const bps = fillDates(parmas.durationVO.start, res.data.bps);
		const latency = fillDates(parmas.durationVO.start, res.data.latency);

		state.opsData = lineTimeHandle(ops, opsMap);
		state.bpsData = lineTimeHandle(bps, opsMap);
		state.delayData = lineTimeHandle(latency, opsMap, (data) => {
			if (typeof (data) !== 'number') return data;
			return parseFloat(data.toFixed(3));
		});
	}).catch((err) => {
		if (err.code === 1604) {
			openRbdMon();
		} else {
			state.opsData = lineTimeHandle();
			state.bpsData = lineTimeHandle();
			state.delayData = lineTimeHandle();
		}
	});
};
// select pool
const changePool = (val:string) => {
	volumeName.value = '';
	poolName.value = val;
	setTimeout(() => {
		isChart.value = false;
	});
};
// select volume
const changeVolume = (val:string) => {
	volumeName.value = val;
	isChart.value = true;
};
const activeTab = inject('activeTab', ref('volume'));
const interval = inject('interval', ref(5000));
const timer = ref();
// Start the timer and call the interface immediately
const openTimer = () => {
	if (!timer.value) {
		getRbdMon();
		timer.value = setInterval(getRbdMon, interval.value);
	}
};
// close Timer
const closeTimer = () => {
	if (timer.value) {
		clearInterval(timer.value);
		timer.value = null;
	}
};
const handle = () => {
	if (activeTab.value === 'volume') {
		if (isChart.value) {
			if (poolName.value && volumeName.value) {
				if (datetimerange.value) {
					getRbdMon();
					closeTimer();
				} else {
					openTimer();
				}
			}
		} else {
			closeTimer();
		}
	} else {
		closeTimer();
	}
};
// Listen to isChart
watch(
	isChart,
	() => {
		handle();
	},
	{
		immediate: true
	}
);
// Listen to pool list data
watch(
	poolList,
	val => {
		poolName.value = val[0]?.poolName;
	},
	{
		immediate: true
	}
);
// Switch to the current tab and turn on polling
watch(
	activeTab,
	() => {
		handle();
	},
	{
		immediate: true
	}
);
// Monitoring time range change
watch(
	datetimerange,
	() => {
		handle();
	},
);
// Monitoring time interval change
watch(
	interval,
	() => {
		// Reset timer
		if (timer.value) {
			clearInterval(timer.value);
			timer.value = setInterval(getRbdMon, interval.value);
		}
	}
);
onUnmounted(() => {
	closeTimer();
});
</script>
<style lang="scss" scoped>

</style>